package com.macrosolution.exdebito


import static org.springframework.http.HttpStatus.*

import com.sun.org.apache.xml.internal.resolver.helpers.PublicId;

import grails.plugin.springsecurity.annotation.Secured;
import grails.transaction.Transactional


/**
 * FileDocumentController
 * A controller class handles incoming web requests and performs actions such as redirects, rendering views and so on.
 */
@Secured(['ROLE_ADMIN','ROLE_AMM'])

class FileDocumentController {
	def springSecurityService

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
	
	def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond FileDocument.list(params), model:[fileDocumentInstanceCount: FileDocument.count()]
    }

	def list(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond FileDocument.list(params), model:[fileDocumentInstanceCount: FileDocument.count()]
    }
	
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
    def show(FileDocument fileDocumentInstance) {
        respond fileDocumentInstance
    }

    def create() {
        respond new FileDocument(params)
    }

    @Transactional
    def save(FileDocument fileDocumentInstance) {
        if (fileDocumentInstance == null) {
            notFound()
            return
        }

        if (fileDocumentInstance.hasErrors()) {
            respond fileDocumentInstance.errors, view:'create'
            return
        }

        fileDocumentInstance.save flush:true

        request.withFormat {
            form {
                flash.message = message(code: 'default.created.message', args: [message(code: 'fileDocumentInstance.label', default: 'FileDocument'), fileDocumentInstance.id])
                redirect fileDocumentInstance
            }
            '*' { respond fileDocumentInstance, [status: CREATED] }
        }
    }

    def edit(FileDocument fileDocumentInstance) {
        respond fileDocumentInstance
    }

    @Transactional
    def update(FileDocument fileDocumentInstance) {
        if (fileDocumentInstance == null) {
            notFound()
            return
        }

        if (fileDocumentInstance.hasErrors()) {
            respond fileDocumentInstance.errors, view:'edit'
            return
        }

        fileDocumentInstance.save flush:true

        request.withFormat {
            form {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'FileDocument.label', default: 'FileDocument'), fileDocumentInstance.id])
                redirect fileDocumentInstance
            }
            '*'{ respond fileDocumentInstance, [status: OK] }
        }
    }

    @Transactional
    def delete(FileDocument fileDocumentInstance) {

        if (fileDocumentInstance == null) {
            notFound()
            return
        }

        fileDocumentInstance.delete flush:true

        request.withFormat {
            form {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'FileDocument.label', default: 'FileDocument'), fileDocumentInstance.id])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'fileDocumentInstance.label', default: 'FileDocument'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }
	
	def upload(){
		DocType dcInstance = DocType.findById(params.documentType.id)
		
		def folder = new File(grailsApplication.config.uploadFolder+File.separator+"Cloud"+File.separator+dcInstance.documentType+File.separator)
		if( !folder.exists() ) {
			
			folder.mkdirs()
		  }
		
		
		if(!(request.getFile('file'))) {
			flash.message = "Il file non deve essere vuoto"
			redirect (action:'create')
		} else {
			def file = request.getFile('file')
			def name_replace = file.originalFilename.replace(' ', '')
			def findName = FileDocument.findByFileNameAndDocumentType(name_replace,dcInstance)
			if(!findName){
				
				def user = springSecurityService.currentUser
				
				
					def docInstance = new FileDocument()
					docInstance.user=user
//					def name_replace = file.originalFilename.replace(' ', '')
					docInstance.fileName = name_replace
					
					docInstance.comments = params.comments
					docInstance.filePath = folder
					docInstance.documentType=dcInstance
					docInstance.file_estension= file.contentType
					docInstance.fileSize=file.size
					
		
					file.transferTo(new File(docInstance.filePath,name_replace))
					docInstance.save(flush:true)
					flash.message = message(code: 'File creato correttamente',)
					redirect (action:'fileHome')
				
			}else{
				
				flash.message = "Esiste gia un file con questo nome"
				redirect (action:'create')
			
			}
			
			
			
		}
		
		
		
	}
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
	def fileHome(){
		
//		def docTypeList = DocType.findAllByDocumentCategory(1)
//		render view:'fileHome.gsp',model:[folders:docTypeList]
		render view:'fileHome.gsp'
		
	}
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
	def load_folder(){
		
		def folders = DocType.findAllByDocumentCategory(1)
		render template:"folderTree", model:[folders:folders]
	
	}
	
	
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
	def filesInFolder(){
		
		DocType folderType = DocType.findByIdAndDocumentCategory(params.folderId,1)
		
		def files = FileDocument.findAllByDocumentType(folderType)
		
		if(files){
			
			if(params.order_by == 'name'){
				
				def filebyname = FileDocument.findAllByDocumentType(folderType)
				
				render template:'fileInDir', model:[files:filebyname.sort{it.fileName.toLowerCase()}]
				
			}else{
				
				def filebydate = FileDocument.findAllByDocumentType(folderType,[sort: 'dateCreated', order: 'desc'])
				render template:'fileInDir', model:[files:filebydate]
			}
		}else{
			render template:'fileInDir', model:[folderType:folderType]
		}
		
		
		
	}
	
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
	def download_file(){
		
		FileDocument fd=  FileDocument.findById(params.fileId)
		
		if(fd){
			def filePath = fd.filePath+File.separator+fd.fileName
			//TODO settare content type on content type del file
			response.setContentType("APPLICATION/OCTET-STREAM")
            response.setHeader("Content-Disposition", "Attachment;Filename=\"${fd.fileName}\"")
            def file = new File(filePath)
            def fileInputStream = new FileInputStream(file)
            def outputStream = response.getOutputStream()
            byte[] buffer = new byte[4096];
            int len;
            while ((len = fileInputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush()
            outputStream.close()
            fileInputStream.close()
			

			
		}else{
			flash.message = message(code:"Non riesco a trovare il file")
			redirect action:"fileHome"
		}
		
	}
	
	def deleteFile(){
		
		def FileDocument fdInstance = FileDocument.findById(params.id)
		
		if(fdInstance){
			DocType dt = fdInstance.documentType
			fdInstance.delete(flush:true)
			def files = FileDocument.findAllByDocumentType(dt,[sort: 'dateCreated', order: 'desc'])
			render template:'fileInDir', model:[files:files]
			
		}else{
			response.status=401
			render "Errore non riesco a trovare il File selezionato"
		}
		
		
	}
	
	def deleteFolder(){
		
		DocType erased = DocType.findById(params.folderId)
		
		if(erased){
			
			if(erased.documentType=="Approfondimenti" || erased.documentType=="Modulistica" || erased.documentType=="Strumenti" ){
				
				response.status=401
//				render "<div class='alert alert-danger fade in'><button class='close' data-dismiss='alert'>&#120;</button><i class='fa-fw fa fa-times'></i><strong>Cartella di sistema!</strong>Non &egrave possibile cancellare questa cartella</div>"
				render "Cartella di sistema!Non &egrave possibile cancellare questa cartella"
				}else{
				
				File folderErased = new File(grailsApplication.config.uploadFolder+File.separator+"Cloud"+ File.separator+erased.documentType)
				if(folderErased.exists()){
					//la cartella esiste cancella 
					
					if(deleteObjects(erased)){
						folderErased.deleteDir()
						erased.delete(flush:true)
						
						def allFolders = DocType.findAllByDocumentCategory(1)
						render template:'/fileDocument/folderTree', model:[folders:allFolders]
						 
					}else{
						response.status=401
//						render "<div class='alert alert-danger fade in'><button class='close' data-dismiss='alert'>&#120;</button><i class='fa-fw fa fa-times'></i><strong>Errore</strong>Non &egrave possibile cancellare questa cartella</div>"
						render "Errore:Impossibile trovare questa cartella!"
					}
					
				
				}else{
//					la cartella non esiste 
					response.status=401
//					render "<div class='alert alert-danger fade in'><button class='close' data-dismiss='alert'>&#120;</button><i class='fa-fw fa fa-times'></i><strong>Errore</strong>Non &egrave possibile cancellare questa cartella</div>"
					render "Errore!Non &egrave possibile cancellare questa cartella"
				}
			
			}
			
		}else{
		
		response.status=401
//		render "<div class='alert alert-danger fade in'><button class='close' data-dismiss='alert'>&#120;</button><i class='fa-fw fa fa-times'></i><strong>Errore!</strong>Impossibile trovare il file</div>"
		render "Errore!Impossibile trovare questa cartella"
		}
	
		
	}
	private deleteObjects(DocType docTypeInst){
		
		def filedocs = FileDocument.findAllByDocumentType(docTypeInst)
		boolean deleted = true
		filedocs.each {FileDocument fd->
			
			if(!fd.delete(flush:true)){
				
				deleted = false
			}
			
			
		}
		
		
		
		return true
		
	}
	
	
	def uploadAj(){
		
		DocType dcInstance = DocType.findById(params.documentType)
		
		def folder = new File(grailsApplication.config.uploadFolder+File.separator+"Cloud"+File.separator+dcInstance.documentType+File.separator)
		if( !folder.exists() ) {
			
			folder.mkdirs()
		  }
		
		
		if(!(request.getFile('file'))) {
			response.status=401
			render "Il file non pu&ograve essere vuoto!"
		} else {
			def file = request.getFile('file')
			def name_replace = file.originalFilename.replace(' ', '')
			def findName = FileDocument.findByFileNameAndDocumentType(name_replace,dcInstance)
			if(!findName){
				
				def user = springSecurityService.currentUser
				
				
					def docInstance = new FileDocument()
					docInstance.user=user
//					def name_replace = file.originalFilename.replace(' ', '')
					docInstance.fileName = name_replace
					
					docInstance.comments = params.comments
					docInstance.filePath = folder
					docInstance.documentType=dcInstance
					docInstance.file_estension= file.contentType
					docInstance.fileSize=file.size
					
		
					file.transferTo(new File(docInstance.filePath,name_replace))
					docInstance.save(flush:true)
					render "File creato correttamente"
				
			}else{
				
				response.status=401
				render "Esiste gi&agrave; un file con questo nome!"
			
			}
			
			
			
		}
		
		
		
	}
	@Secured(['ROLE_ADMIN','ROLE_AMM','ROLE_CC','ROLE_AVV','ROLE_C','ROLE_SC','ROLE_BCKOFF'])
	def showFileDetail(){
		
		def fileId = params.fileId
		FileDocument fd = FileDocument.findById(fileId)
		
		if(fd){
			render template:'filedetailpopup', model:[fd:fd]
		}else{
			
			response.status=401
			render "Impossibile recuperare le inforamazioni del file,riprovare piu tardi.."
		
		}
		
	}
	
	def showuploadp(){
		
		render template:"uploadpopup"
		
	}
	
}
